#pragma once

#include "log.hpp"
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

using namespace std;

enum
{
    USAGE_ERR = 10,
    SOCK_ERR,
    READ_ERR,
    CONNECT_ERR
};

class Client
{
public:
    Client(const string &ip, uint16_t port)
        : _sock(-1), _serverIp(ip), _serverPort(port)
    {
    }

    void initClient()
    {
        // 1.创建套接字
        _sock = socket(AF_INET, SOCK_STREAM, 0);
        if (_sock < 0)
        {
            logMessage(FATAL, "创建套接字失败");
            exit(SOCK_ERR);
        }
        logMessage(NORMAL, "创建套接字成功");

        // 2. 这里和UDP一样，还是由操作系统分配端口号，并完成绑定。
    }

    void start()
    {

        // 3.发送链接请求
        struct sockaddr_in server;
        memset(&server, 0, sizeof(server));
        server.sin_family = AF_INET;
        server.sin_port = htons(_serverPort);
        server.sin_addr.s_addr = inet_addr(_serverIp.c_str());
        int n = connect(_sock, (struct sockaddr *)&server, sizeof(server));
        if (n != 0)
        {
            logMessage(ERROR, "链接失败");
            exit(CONNECT_ERR);
        }
        logMessage(NORMAL, "链接成功");

        while (1)
        {
            // 4.读写
            string message;
            cout << "请输入# ";
            getline(cin, message);  //这样只发送回车会出问题

            write(_sock, message.c_str(), message.size());

            char buf[1024];
            n = read(_sock, buf, sizeof(buf) - 1);
            if (n < 0)
            {
                logMessage(FATAL, "接收失败");
                exit(READ_ERR);
            }
            buf[n] = 0;
            cout <<"服务端回复：" <<buf << endl;
        }
    }

    ~Client()
    {
    }

private:
    int _sock;
    string _serverIp;
    uint16_t _serverPort;
};